from langchain.text_splitter import CharacterTextSplitter,MarkdownTextSplitter,RecursiveCharacterTextSplitter
# from langchain.document_loaders import UnstructuredFileLoader,UnstructuredMarkdownLoader,UnstructuredWordDocumentLoader
import os
from fastapi import APIRouter, Query, UploadFile, File,Form,Body
from xingchen import Configuration, CharacterPermissionConfig,ApiClient, ChatApiSub, ChatReqParams,CharacterUpdateDTO, CharacterKey, Message, UserProfile, ModelParameters,ChatContext,CharacterCreateDTO,CharacterApiSub
import time
from fastapi.concurrency import run_in_threadpool
from typing import Optional
from pydantic import BaseModel
from embeddingDB import pgDB
from typing import Dict, Any
 
router = APIRouter(
    prefix= "/roleAgent",
    tags= ["roleAgentRouter"],
    responses= {404: {"description": "Not found path knowledge"}}
)



def initCharacterApiSubClient():
    configuration = Configuration(
        host="https://nlp.aliyuncs.com"
    )
    # global xingchenAK
    xingchenAK = "lm-qbcQwj0A9CKMEBu4YkVe6Q=="
    configuration.access_token = xingchenAK
    with ApiClient(configuration) as api_client:
        api_instance = CharacterApiSub(api_client)
    return api_instance


def initChatClient():
    configuration = Configuration(
        host="https://nlp.aliyuncs.com"
    )
    xingchenAK = "lm-qbcQwj0A9CKMEBu4YkVe6Q=="
    configuration.access_token = xingchenAK
    with ApiClient(configuration) as api_client:
        api_instance = ChatApiSub(api_client)
    return api_instance


xingchenCharacterAPI = initCharacterApiSubClient()
xingchenChatAPI = initChatClient()
# # 非流式回复
# def test_chat_sync():
#     chat_param = build_chat_param()
#     res = api.chat(chat_param)
#     print(res.to_str())

class userMessage(BaseModel):
    character_id: Optional[str] = ""
    nick_name: Optional[str] = ""
    user_id: Optional[str] = ""
    content: Optional[str] = ""


def build_chat_param(msg:userMessage):
    return ChatReqParams(
        bot_profile=CharacterKey(
            character_id=msg.character_id
        ),
        model_parameters=ModelParameters(
            seed=int(time.time()),
            incrementalOutput=False
        ),
        messages=[
            Message(
                name =msg.nick_name,
                role='user',
                content=msg.content
            )
        ],
        context=ChatContext(
            use_chat_history=True
        ),
        user_profile=UserProfile(
            user_id=msg.user_id,
            user_name=msg.nick_name
        )
    )
    
# # 流式回复
# @router.post("/chatAsync")
def generate_text_from_xingchen(msg:userMessage):
    chat_param = build_chat_param(msg)
    chat_param.streaming = True
    responses = xingchenChatAPI.chat(chat_param)
    # for res in responses:
    #     print(res.data.choices[0].messages[0].content)
        
    # 假设 API 返回的是一个文本流
    for res in responses:
        reply = res.data.choices[0].messages[0].content
        print(reply)
        yield reply
        
from fastapi.responses import StreamingResponse
@router.post("/chatAsync")
async def chatAsync(msg:userMessage):
    return StreamingResponse(generate_text_from_xingchen(msg), media_type="text/plain")
# test_chat_async()
# test_chat_sync()

# work_dir = "."lm-qbcQwj0A9CKMEBu4YkVe6Q==

# 转换函数
def snake_to_camel(s: str) -> str:
    parts = s.split('_')
    return parts[0].lower() + ''.join(x.capitalize() for x in parts[1:])
 
# 递归转换字典键的函数
def convert_keys_to_camel(d: Dict[str, Any]) -> Dict[str, Any]:
    if isinstance(d, dict):
        return {snake_to_camel(k): convert_keys_to_camel(v) for k, v in d.items()}
    elif isinstance(d, list):
        return [convert_keys_to_camel(item) for item in d]
    else:
        return d
from datetime import datetime
class roleAgent(BaseModel):
    id:Optional[int] = 0
    character_id: Optional[str] = ""
    name: Optional[str] = "美髯公关云长"
    introduction: Optional[str] = "满腔忠义的关云长"
    basic_information: Optional[str] = "我们来玩一个角色扮演的游戏， 你是「满腔忠义的关云长」。"
    opening_line: Optional[str] = "我是「关云长」，很高心与你玩游戏"
    traits: Optional[str] = "请在对话时尽可能的展现你的性格、感情， 用文言文回答， 并使用古人的语气和用词。"
    chat_example: Optional[str] = ""
    type: Optional[str] = "virtual"
    chat_objective: Optional[str] = "我要关羽拜把子"
    sound: Optional[str] = ""
    # role_types: Optional[str] = ""
    create_time: Optional[datetime] = ""
    
    
    
@router.post("/createRoleAgent")
def createRoleAgent(params:roleAgent):
    rs = {"code":200,"msg":"创建成功","data":{}}
    name = params.name
    print(params)
    # 角色管理准备部分已省略

    # api = init_client()
    body = CharacterCreateDTO(
        name=name,
        introduction=params.introduction,
        basicInformation=params.basic_information,
        openingLine=params.opening_line,
        traits=params.traits,
        chatObjective=params.chat_objective,
        permConfig=CharacterPermissionConfig(
            allowApi=0,
            allowChat=0,
            isPublic=0,
        ),
    )
    result = xingchenCharacterAPI.create(character_create_dto=body)
    print(result.data)
    
    
    sql = '''
    INSERT INTO role_agent(name,character_id,opening_line,traits,chat_objective,basic_information,introduction,sound)
    VALUES('{}','{}','{}','{}','{}','{}','{}','{}')
    '''.format(name,result.data.character_id,params.opening_line,params.traits,params.chat_objective,params.basic_information,params.introduction,params.sound)
    db = pgDB()
    db.modify(sql)
    db.close()
    
    
    # k = embeddingDB.VectorDB()
    # k.getCollection(title)
    # print()
    rs["data"] = result.data
    return rs


@router.post("/updateRoleAgent")
def updateRoleAgent(params:roleAgent):
    rs = {"code":200,"msg":"修改成功","data":{}}
    # name = params.name
    print(params)
    # 角色管理准备部分已省略

    # api = init_client()
    body = CharacterUpdateDTO(
        characterId=params.character_id,
        name=params.name,
        introduction=params.introduction,
        basicInformation=params.basic_information,
        openingLine=params.opening_line,
        traits=params.traits,
        chatObjective=params.chat_objective,
        
        permConfig=CharacterPermissionConfig(
            allowApi=0,
            allowChat=0,
            isPublic=0,
        ),
    )
    result = xingchenCharacterAPI.update(character_update_dto=body)
    print(result.data)
    
    
    sql = '''
    UPDATE role_agent
    SET name='{}',opening_line='{}',traits='{}',chat_objective='{}',basic_information='{}',introduction='{}',sound='{}'
    WHERE id='{}'
    
    '''.format(params.name,params.opening_line,params.traits,params.chat_objective,params.basic_information,params.introduction,params.sound,params.id)
    db = pgDB()
    print(sql)
    db.modify(sql)
    db.close()
    
    
    # k = embeddingDB.VectorDB()
    # k.getCollection(title)
    # print()
    rs["data"] = result.data
    return rs

    
@router.post("/getRoleAgentList")
async def getRoleAgentList(params:roleAgent):
    rs = {"code":200,"msg":"查询成功","data":{}}
    # title = params.title
    # print(params)
    
    sql = '''
    SELECT *
    FROM role_agent
    '''
    db = pgDB()
    data = await run_in_threadpool(db.select, sql)
    db.close()
    
    # data = [ convert_keys_to_camel(roleAgent(**d).dict()) for d in data]
    # data = data.dict()  # 将 Pydantic 模型转换为字典
    # data = convert_keys_to_camel(data)  # 将字典键转换为驼峰命名
    
    rs["data"] = data
    # print(">>",rs["data"])
    return rs
    
@router.post("/deleteRoleAgent")
def deleteRoleAgent(params:roleAgent):
    rs = {"code":200,"msg":"删除成功","data":{}}
    print(params)
    sql = '''
    DELETE FROM role_agent 
    WHERE id = '{}'
    '''.format(params.id)
    db = pgDB()
    data = db.modify(sql)
    result = xingchenCharacterAPI.delete(character_id=params.character_id)
    print(result.data)
    rs["data"] = result
    db.close()
    
    # k.delroleAgent(params.title)
    
    return rs
    
@router.post("/getRoleAgentInfo")
def getRoleAgentInfo(params:roleAgent):
    rs = {"code":200,"msg":"查询成功","data":{}}
    # title = params.title
    # print(params)
    
    sql = '''
    SELECT * 
    FROM role_agent
    WHERE id = '{}'
    '''.format(params.id)
    print(sql)
    db = pgDB()
    
    data = db.select(sql)[0]
    data = roleAgent(**data)
    # data = data.dict()  # 将 Pydantic 模型转换为字典
    # data = convert_keys_to_camel(data)  # 将字典键转换为驼峰命名
    
    # roleAgentInfo = xingchenCharacterAPI.character_details(character_id=data.character_id)
    # print(roleAgentInfo.data)
    db.close()
    
    # rs["data"] = data
    # db.close()
    # print(">>",rs["data"])
    # print()
    # try:
    #     fileList = [{"fileName":f } for f in os.listdir("./uploadFiles/{}".format(params.id))]
    # except:
    #     fileList=[]
    # print(kList)
    # k.delroleAgent(params.title)
    rs["data"] = data
    return rs
    
    
